﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace Angle.Krill.Utils
{
    public static class EnumHelper
    {
        /// <summary>
        /// 获取枚举集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<EnumInfo> GetEnumInfo<T>()
        {
            var t = typeof(T);

            return GetEnumInfo(t);
        }
        /// <summary>
        /// 根据值获取枚举自定义属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumType">枚举类型，字符串</param>
        /// <returns></returns>
        public static List<T> GetCustomAttributes<T>(Type t, string enumType, bool igoreCase = true) where T : Attribute
        {
            if (null == t || !t.IsEnum)
            {
                return null;
            }
            List<T> lst = new List<T>();
            foreach (var item in Enum.GetValues(t))
            {
                string orgType = item?.ToString();
                if (igoreCase)
                {
                    orgType = orgType.ToLower();
                    enumType = enumType.ToLower();
                }
                if (orgType == enumType)
                {
                    var attrs = item.GetType().GetField(item.ToString()).GetCustomAttributes(typeof(T), true);
                    if (attrs != null && attrs.Length > 0)
                    {
                        foreach (var attr in attrs)
                        {
                            if (attr is T)
                            {
                                lst.Add(attr as T);
                            }
                        }
                    }
                }
            }

            return lst;
        }
        /// <summary>
        /// 获取枚举集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<EnumInfo> GetEnumInfo(Type t)
        {
            List<EnumInfo> eInfo = new List<EnumInfo>();
            if (null == t || !t.IsEnum)
            {
                return eInfo;
            }
            string desc = string.Empty;
            foreach (var item in Enum.GetValues(t))
            {
                var attrs = item.GetType().GetField(item.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), true);
                if (attrs != null && attrs.Length > 0)
                {
                    DescriptionAttribute descAttr = attrs[0] as DescriptionAttribute;
                    desc = descAttr.Description;
                }
                eInfo.Add(new EnumInfo
                {
                    Description = desc,
                    Value = Convert.ToInt32(item),
                    Type = item.ToString()
                });
            }

            return eInfo;
        }
        /// <summary>
        /// 将字符串或描述信息转成枚举
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public static T ConvertTo<T>(string name, bool ignoreCase = true) where T : Enum
        {
            if (string.IsNullOrEmpty(name))
            {
                return default;
            }
            List<EnumInfo> controlTypes = EnumHelper.GetEnumInfo<T>();
            IEnumerable<EnumInfo> lst = null;
            if (ignoreCase)
            {
                string tmp = name.ToLower();
                lst = controlTypes.Where(c => c.Type.ToLower() == tmp || c.Description == tmp);
            }
            else
            {
                lst = controlTypes.Where(c => c.Type == name || c.Description == name);
            }
            if (lst.Any())
            {
                var v = lst.FirstOrDefault();
                if (null == v)
                {
                    return default;
                }
                return v.Type.ToEnum<T>();
            }

            return default;
        }
    }
    /// <summary>
    /// 枚举信息
    /// </summary>
    public class EnumInfo
    {
        /// <summary>
        /// 值
        /// </summary>
        public int Value { get; set; }
        /// <summary>
        /// 类型
        /// </summary>
        public string Type { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public string Description { get; set; }
    }
}
